﻿/********************************************************************
	created:	2011/05/29
	created:	29:5:2011   21:06
	filename: 	D:\My Documents\Visual Studio 2010\Projects\IntranetMessagerClient\Client\ClientCallback.cs
	file path:	D:\My Documents\Visual Studio 2010\Projects\IntranetMessagerClient\Client
	file base:	ClientCallback
	file ext:	cs
	author:		
	
	purpose:	客户端回调接口实现
*********************************************************************/
using System;
using System.Collections.Generic;
using System.Threading;
using System.Windows.Forms;
using Client.Async_ServiceReference;
using CommonLibrary;

namespace Client
{
    internal class ClientCallback : IServiceRepositoryCallback
    {
        private readonly Dictionary<string, MessageDelegate> _messageHandleList =
            new Dictionary<string, MessageDelegate>();

        private readonly ReaderWriterLockSlim _rwLocker = new ReaderWriterLockSlim();

        public ClientCallback()
        {
            MessageHandlerListInit();
        }

        #region IServiceRepositoryCallback Members

        void IServiceRepositoryCallback.SendBack(byte[] message)
        {
            var envelope = Functions.DeserializeFromBytes<Protocol.MessageEnvelope>(message);
            if (envelope.Signed && (!CryptoClient.RsaVerifyHash(envelope.HashCode, envelope.ByteMessage)))
            {
                MessageBox.Show(@"无法验证数据可靠性！放弃数据处理", @"致命安全性错误！", MessageBoxButtons.OK, MessageBoxIcon.Warning,
                                MessageBoxDefaultButton.Button1);
                return;
            }
            MessageDelegate handler = null;
            _rwLocker.EnterReadLock();
            try
            {
                if (envelope.MessageType != null)
                {
                    if (envelope.MessageType.FullName != null)
                        _messageHandleList.TryGetValue(envelope.MessageType.FullName, out handler);
                }
                if (handler != null)
                    handler.BeginInvoke(message, null, null);
            }
            catch (Exception)
            {
                MessageBox.Show(@"Select Message Handler error", @"Error!", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            finally
            {
                _rwLocker.ExitReadLock();
            }
        }

        IAsyncResult IServiceRepositoryCallback.BeginSendBack(byte[] message, AsyncCallback callback, object asyncState)
        {
            throw new NotImplementedException();
        }

        void IServiceRepositoryCallback.EndSendBack(IAsyncResult result)
        {
            throw new NotImplementedException();
        }

        #endregion

        private void MessageHandleListAdd(string fullName, MessageDelegate handler)
        {
            _rwLocker.EnterWriteLock();
            try
            {
                if (fullName != null)
                    if (!_messageHandleList.ContainsKey(fullName))
                        _messageHandleList.Add(fullName, handler);
            }
            catch (Exception)
            {
                MessageBox.Show(@"Message Handle List add error", @"Error!", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            finally
            {
                _rwLocker.ExitWriteLock();
            }
        }

        private void MessageHandlerListInit()
        {
            MessageHandleListAdd(typeof (Protocol.SignIn).FullName,
                                 ClientCallbackFunction.SignInProcessdure);
            MessageHandleListAdd(typeof (Protocol.TalkingPackage).FullName,
                                 ClientCallbackFunction.TalkingProcessdure);
            MessageHandleListAdd(typeof (Protocol.RegNewUser).FullName,
                                 ClientCallbackFunction.RegNewUserProcessdure);
            MessageHandleListAdd(typeof (Protocol.GetOnlineUsers).FullName,
                                 ClientCallbackFunction.QueryAllOnlineUserProcessdure);
            MessageHandleListAdd(typeof (Protocol.DesKeyUpdate).FullName,
                                 ClientCallbackFunction.DesKeyUpdateProcessdure);
            MessageHandleListAdd(typeof (Protocol.DesKeyUpdateAck).FullName,
                                 ClientCallbackFunction.DesKeyUpdateAckProcessdure);
        }

        #region Nested type: MessageDelegate

        private delegate void MessageDelegate(byte[] byteMessage);

        #endregion
    }
}